export const loadText = (filePath) => {
  var request = new XMLHttpRequest();
  request.open('GET', filePath, false);
  request.send();
  return request.responseText;
};

export const getFullscreenQuad = () => {
  // @ts-ignore
  var fullscreenQuad = new Cesium.Geometry({
    // @ts-ignore
    attributes: new Cesium.GeometryAttributes({
      // @ts-ignore
      position: new Cesium.GeometryAttribute({
        // @ts-ignore
        componentDatatype: Cesium.ComponentDatatype.FLOAT,
        componentsPerAttribute: 3,
        //  v3----v2
        //  |     |
        //  |     |
        //  v0----v1
        // @ts-ignore
        values: new Float32Array([
          -1,
          -1,
          0, // v0
          1,
          -1,
          0, // v1
          1,
          1,
          0, // v2
          -1,
          1,
          0 // v3
        ])
      }),
      // @ts-ignore
      st: new Cesium.GeometryAttribute({
        // @ts-ignore
        componentDatatype: Cesium.ComponentDatatype.FLOAT,
        componentsPerAttribute: 2,
        // @ts-ignore
        values: new Float32Array([0, 0, 1, 0, 1, 1, 0, 1])
      })
    }),
    indices: new Uint32Array([3, 2, 0, 0, 2, 1])
  });
  return fullscreenQuad;
};

export const createTexture = (options, typedArray) => {
  // @ts-ignore
  if (Cesium.defined(typedArray)) {
    // typed array needs to be passed as source option, this is required by Cesium.Texture
    var source = {};
    source.arrayBufferView = typedArray;
    options.source = source;
  }

  // @ts-ignore
  var texture = new Cesium.Texture(options);
  return texture;
};

export const createFramebuffer = (context, colorTexture, depthTexture) => {
  // @ts-ignore
  var framebuffer = new Cesium.Framebuffer({
    context: context,
    colorTextures: [colorTexture],
    depthTexture: depthTexture
  });
  return framebuffer;
};

export const createRawRenderState = (options) => {
  var translucent = true;
  var closed = false;
  var existing = {
    viewport: options.viewport,
    depthTest: options.depthTest,
    depthMask: options.depthMask,
    blending: options.blending
  };

  // @ts-ignore
  var rawRenderState = Cesium.Appearance.getDefaultRenderState(translucent, closed, existing);
  return rawRenderState;
};

export const viewRectangleToLonLatRange = (viewRectangle) => {
  var range = {};

  // @ts-ignore
  var postiveWest = Cesium.Math.mod(viewRectangle.west, Cesium.Math.TWO_PI);
  // @ts-ignore
  var postiveEast = Cesium.Math.mod(viewRectangle.east, Cesium.Math.TWO_PI);
  var width = viewRectangle.width;

  var longitudeMin;
  var longitudeMax;
  // @ts-ignore
  if (width > Cesium.Math.THREE_PI_OVER_TWO) {
    longitudeMin = 0.0;
    // @ts-ignore
    longitudeMax = Cesium.Math.TWO_PI;
  } else {
    if (postiveEast - postiveWest < width) {
      longitudeMin = postiveWest;
      longitudeMax = postiveWest + width;
    } else {
      longitudeMin = postiveWest;
      longitudeMax = postiveEast;
    }
  }

  range.lon = {
    // @ts-ignore
    min: Cesium.Math.toDegrees(longitudeMin),
    // @ts-ignore
    max: Cesium.Math.toDegrees(longitudeMax)
  };

  var south = viewRectangle.south;
  var north = viewRectangle.north;
  var height = viewRectangle.height;

  // @ts-ignore
  var extendHeight = height > Cesium.Math.PI / 12 ? height / 2 : 0;
  // @ts-ignore
  var extendedSouth = Cesium.Math.clampToLatitudeRange(south - extendHeight);
  // @ts-ignore
  var extendedNorth = Cesium.Math.clampToLatitudeRange(north + extendHeight);

  // extend the bound in high latitude area to make sure it can cover all the visible area
  // @ts-ignore
  if (extendedSouth < -Cesium.Math.PI_OVER_THREE) {
    // @ts-ignore
    extendedSouth = -Cesium.Math.PI_OVER_TWO;
  }
  // @ts-ignore
  if (extendedNorth > Cesium.Math.PI_OVER_THREE) {
    // @ts-ignore
    extendedNorth = Cesium.Math.PI_OVER_TWO;
  }

  range.lat = {
    // @ts-ignore
    min: Cesium.Math.toDegrees(extendedSouth),
    // @ts-ignore
    max: Cesium.Math.toDegrees(extendedNorth)
  };

  return range;
};

/**
 * 乱序数组求最大最小值，性能略优于 Math.max / min 方法。支持 TypedArray 和普通数字数组。
 *
 * @param {[]|ArrayBufferView} arr 数组
 * @param {boolean} max 默认是 true，即求最大值；false 为求最小值
 * @returns
 */
export const minmax = (arr, max = true) => {
  if (!(arr instanceof Array) && !ArrayBuffer.isView(arr)) {
    return;
  }
  // @ts-ignore
  const length = arr.length;
  if (length === 0) {
    return;
  }
  if (length === 1) {
    return arr[0];
  }

  let value = arr[0];
  for (let i = 1; i < length; ++i) {
    if (max ? arr[i] > value : arr[i] < value) {
      value = arr[i];
    }
  }
  return value;
};
